home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch15 / Pline3d.cls < prev    next >
Text File  |  1999-06-24  |  6KB  |  218 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "Polyline3d"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = False
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' Point3D and Segment3D are defined in module M3OPS.BAS as:
  17. '    Type Point3D
  18. '        coord(1 To 4) As Single
  19. '        trans(1 To 4) As Single
  20. '    End Type
  21. '
  22. '    Type Segment3D
  23. '        pt1 As Integer
  24. '        pt2 As Integer
  25. '    End Type
  26.  
  27. Private NumPoints As Integer ' Number of points.
  28. Private Points() As Point3D  ' Data points.
  29.  
  30. Private NumSegs As Integer   ' Number of segments.
  31. Private Segs() As Segment3D  ' The segments.
  32.  
  33. ' Create a pyramid with height L and base given
  34. ' by the points in the coord array. Add the
  35. ' segments that make up the pyramid to this
  36. ' polyline.
  37. Public Sub Stellate(L As Single, ParamArray coord() As Variant)
  38. Dim x0 As Single
  39. Dim y0 As Single
  40. Dim z0 As Single
  41. Dim x1 As Single
  42. Dim y1 As Single
  43. Dim z1 As Single
  44. Dim x2 As Single
  45. Dim y2 As Single
  46. Dim z2 As Single
  47. Dim x3 As Single
  48. Dim y3 As Single
  49. Dim z3 As Single
  50. Dim Ax As Single
  51. Dim Ay As Single
  52. Dim Az As Single
  53. Dim Bx As Single
  54. Dim By As Single
  55. Dim Bz As Single
  56. Dim Nx As Single
  57. Dim Ny As Single
  58. Dim Nz As Single
  59. Dim num As Integer
  60. Dim i As Integer
  61. Dim pt As Integer
  62.  
  63.     num = (UBound(coord) + 1) \ 3
  64.     If num < 3 Then
  65.         MsgBox "Must have at least 3 points to stellate.", , vbExclamation
  66.         Exit Sub
  67.     End If
  68.     
  69.     ' (x0, y0, z0) is the center of the polygon.
  70.     x0 = 0
  71.     y0 = 0
  72.     z0 = 0
  73.     pt = 0
  74.     For i = 1 To num
  75.         x0 = x0 + coord(pt)
  76.         y0 = y0 + coord(pt + 1)
  77.         z0 = z0 + coord(pt + 2)
  78.         pt = pt + 3
  79.     Next i
  80.     x0 = x0 / num
  81.     y0 = y0 / num
  82.     z0 = z0 / num
  83.     
  84.     ' Find the normal.
  85.     x1 = coord(0)
  86.     y1 = coord(1)
  87.     z1 = coord(2)
  88.     x2 = coord(3)
  89.     y2 = coord(4)
  90.     z2 = coord(5)
  91.     x3 = coord(6)
  92.     y3 = coord(7)
  93.     z3 = coord(8)
  94.     Ax = x2 - x1
  95.     Ay = y2 - y1
  96.     Az = z2 - z1
  97.     Bx = x3 - x2
  98.     By = y3 - y2
  99.     Bz = z3 - z2
  100.     m3Cross Nx, Ny, Nz, Ax, Ay, Az, Bx, By, Bz
  101.     
  102.     ' Give the normal length L.
  103.     m3SizeVector L, Nx, Ny, Nz
  104.     
  105.     ' The normal + <x0, y0, z0> gives the point.
  106.     x0 = x0 + Nx
  107.     y0 = y0 + Ny
  108.     z0 = z0 + Nz
  109.  
  110.     ' Build the segments that make up the object.
  111.     x1 = coord(3 * num - 3)
  112.     y1 = coord(3 * num - 2)
  113.     z1 = coord(3 * num - 1)
  114.     pt = 0
  115.     For i = 1 To num
  116.         x2 = coord(pt)
  117.         y2 = coord(pt + 1)
  118.         z2 = coord(pt + 2)
  119.         AddSegment x1, y1, z1, x2, y2, z2, x0, y0, z0
  120.         x1 = x2
  121.         y1 = y2
  122.         z1 = z2
  123.         pt = pt + 3
  124.     Next i
  125. End Sub
  126.  
  127. ' Add one or more line segments to the polyline.
  128. Public Sub AddSegment(ParamArray coord() As Variant)
  129. Dim num_segs As Integer
  130. Dim i As Integer
  131. Dim last As Integer
  132. Dim pt As Integer
  133.  
  134.     num_segs = (UBound(coord) + 1) \ 3 - 1
  135.     ReDim Preserve Segs(1 To NumSegs + num_segs)
  136.  
  137.     last = AddPoint((coord(0)), (coord(1)), (coord(2)))
  138.     pt = 0
  139.     For i = 1 To num_segs
  140.         Segs(NumSegs + i).pt1 = last
  141.         pt = pt + 3
  142.         last = AddPoint((coord(pt)), (coord(pt + 1)), (coord(pt + 2)))
  143.         Segs(NumSegs + i).pt2 = last
  144.     Next i
  145.  
  146.     NumSegs = NumSegs + num_segs
  147. End Sub
  148. ' Add a point to the polyline or reuse a point.
  149. ' Return the point's index.
  150. Private Function AddPoint(ByVal X As Single, ByVal Y As Single, ByVal Z As Single) As Integer
  151. Dim i As Integer
  152.  
  153.     ' See if the point is already here.
  154.     For i = 1 To NumPoints
  155.         If X = Points(i).coord(1) And _
  156.            Y = Points(i).coord(2) And _
  157.            Z = Points(i).coord(3) Then _
  158.                 Exit For
  159.     Next i
  160.     AddPoint = i
  161.     
  162.     ' If so, we're done.
  163.     If i <= NumPoints Then Exit Function
  164.     
  165.     ' Otherwise create the new point.
  166.     NumPoints = NumPoints + 1
  167.     ReDim Preserve Points(1 To NumPoints)
  168.     Points(i).coord(1) = X
  169.     Points(i).coord(2) = Y
  170.     Points(i).coord(3) = Z
  171.     Points(i).coord(4) = 1#
  172. End Function
  173.  
  174.  
  175. ' Apply a transformation matrix which may not
  176. ' contain 0, 0, 0, 1 in the last column to the
  177. ' object.
  178. Public Sub ApplyFull(M() As Single)
  179. Dim i As Integer
  180.  
  181.     For i = 1 To NumPoints
  182.         m3ApplyFull Points(i).coord, M, Points(i).trans
  183.     Next i
  184. End Sub
  185.  
  186. ' Apply a transformation matrix to the object.
  187. Public Sub Apply(M() As Single)
  188. Dim i As Integer
  189.  
  190.     For i = 1 To NumPoints
  191.         m3Apply Points(i).coord, M, Points(i).trans
  192.     Next i
  193. End Sub
  194.  
  195.  
  196. ' Draw the transformed points on a PictureBox.
  197. Public Sub Draw(ByVal pic As PictureBox, Optional R As Variant)
  198. Dim seg As Integer
  199. Dim pt1 As Integer
  200. Dim pt2 As Integer
  201. Dim dist As Single
  202.  
  203.     On Error Resume Next
  204.     If IsMissing(R) Then R = INFINITY
  205.     dist = R
  206.     For seg = 1 To NumSegs
  207.         pt1 = Segs(seg).pt1
  208.         pt2 = Segs(seg).pt2
  209.         ' Don't draw if either point is farther
  210.         ' from the focus point than the center of
  211.         ' projection (which is distance dist away).
  212.         If (Points(pt1).trans(3) < R) And (Points(pt2).trans(3) < R) Then _
  213.             pic.Line _
  214.                 (Points(pt1).trans(1), Points(pt1).trans(2))- _
  215.                 (Points(pt2).trans(1), Points(pt2).trans(2))
  216.     Next seg
  217. End Sub
  218.